import { userInfo } from '@/utils/helper';
import { message, notification } from 'antd';
import store from 'storejs';
import Decimal from 'decimal.js';
import dayjs from 'dayjs';

export const localUserInfo = () => store.get('userInfo');

// 使用big处理数字
export const jingDuNum = (num: number | string) => new Decimal(num);

// api的key、url等信息
export const keyInfo = {
  prod: {
    key: store.get('zhima')?.key,
    secret: store.get('zhima')?.secret,
    url: 'https://api.gateio.ws/api/v4',
  },
};

export const gateKey = { ...keyInfo.prod };

// 获取当前时间戳
export const getTime = () => parseInt((new Date().getTime() / 1000).toString(), 10);

// 将数字转换为万
export function convertToTenThousand(num: number, decimalPlaces = 2) {
  const absNum = Math.abs(num);
  if (absNum >= 10000) {
    const result = (absNum / 10000).toFixed(decimalPlaces);
    return (num < 0 ? '-' : '') + result + '万';
  }
  return num.toString();
}

// 将枚举转换为数组
export const enumToArray = (data: any) =>
  Object.entries(data).map(([key, value]) => ({ name: value, value: key }));

// 将数组转换为枚举
export const arrayToEnum = (data: any) =>
  Object.fromEntries(data.map((item: any) => [item.name, item.value]));

// 将数组转换为枚举2
export const arrayToEnum2 = (data: any) =>
  Object.fromEntries(data.map((item: any) => [item.value, item.label]));

export const wait = (num = 1000) => new Promise((resolve) => setTimeout(resolve, num));

// 检测接口是否成功
export const isSuccess = (res: any, showError = true) => {
  if (res?.code !== 10000) {
    if (showError) {
      message.open({
        content: res?.msg,
        type: 'error',
      });
    }
    return false;
  }
  return true;
};

// 下单时的特殊备注，参数四为时间
export const orderText = `t-h-${store.get('userInfo')?.id}-${(new Date().getTime() / 1000).toFixed(0)}`;

// 生效方式
export const tifTypes: any = {
  gtc: '普通委托',
  ioc: '立即成交或取消',
  poc: '被动委托',
  fok: '完全成交或取消',
};

// 订单结束方式
export const orderStatusTypes: any = {
  filled: '完全成交',
  cancelled: '已撤销',
  liquidated: '强平撤销',
  ioc: '未立即完全成交',
  auto_deleveraged: '自动减仓撤销',
  reduce_only: '增持仓位撤销，因为设置reduce_only或平仓',
};

// 来源
export const sourceTypes = (text: string) => {
  if (text.includes('web')) return '网页';
  if (text.includes('app')) return '移动端';
  if (text.includes('liq')) return '强制平仓';
  if (text.includes('ao')) return '止盈/止损';
  if (text.includes('close_all')) return '一键平仓';
  return text;
};

// 将时间转化为时间戳
export const getTimestamp = (time: string) =>
  parseInt((new Date(time).getTime() / 1000).toString(), 10);

// 检测是否是localhost
export const isLocal = () => window.location.hostname === 'localhost';

// 格式化数字，添加千分位,数字，保留位数
export function formatNum(num: any, fixed = 2) {
  const _num = Number(num).toFixed(fixed);
  const numStr = _num.toString();
  const [integerPart, decimalPart] = numStr.split('.');
  const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  return decimalPart ? `${formattedInteger}.${decimalPart}` : formattedInteger;
}

// 格式化数字单位
export function formatNumUnit(number: any, decimalPlaces = 2) {
  const num = Number(number);
  if (Math.abs(num) >= 1e8) {
    // 如果数字的绝对值大于等于 1 亿
    return (num / 1e8).toFixed(decimalPlaces) + '亿';
  } else if (Math.abs(num) >= 1e4) {
    // 如果数字的绝对值大于等于 1 万
    return (num / 1e4).toFixed(decimalPlaces) + '万';
  }
  // 数字小于 1 万，直接返回原数字并保留指定小数位数
  return num.toFixed(decimalPlaces);
}

// 保留小数不四舍五入
export function numNoSiWu(num: any, n: number = 2) {
  const multiplier = Math.pow(10, n);
  return Math.floor(num * multiplier) / multiplier;
}

// 根据员工区分订单
export function getOrderByUser(list: any) {
  if (!Array.isArray(list) || list.length === 0) return [];
  return list.filter((item: any) => Number(item.text?.split('-')[2]) === userInfo?.id);
  // return list; // 不区分
}

export function notify(message = '错误提示', type = 'error') {
  console.log('notify');
  // const placement = 'top';
  notification.error({
    message,
  });
  // notification.config({
  //   placement: 'top',
  //   bottom: 50,
  //   duration: 3,
  //   rtl: true,
  // });
}

// 计算数组累积和
export function arrSum(list: any[]) {
  const arr = list?.reverse();
  let sum = 0;
  return arr
    .map((num) => {
      sum += num;
      return sum;
    })
    .reverse();
}

/*
size = 钱 / (价格 * 合约乘数)，取整
*/
// 列表计算usdt数量,size仓位的size有变化
export const getUsdtNum = (record: any, size = null) => {
  const newSize = size || record?.size;
  let res = countUsdtNum(record?.price, newSize, record?.contractInfo?.quanto_multiplier);
  return res;
};

// 计算usdt数量
export const countUsdtNum = (price: any, size: any, chengShu: any) => {
  let res: any = (price * size * chengShu).toFixed(1);
  if (!getUserDirection()) res = -1 * res;
  return res;
};

// 计算usdt数量
export const countUsdtNumNew = (price: any, size: any, chengShu: any) => {
  let res: any = chengFa([price, size, chengShu]).toFixed(1);
  return res;
};

// 检测是否为NaN
export const handleNan = (num: any, isToFixed = true) => {
  if (!num || Number.isNaN(num)) {
    return '--';
  } else {
    return isToFixed ? num.toFixed(2) : num;
  }
};

// 获取用户交易方向 ,+-
export const getUserDirectionNum = () => store('userInfo')?.direction;

// 获取用户交易方向
export const getUserDirection = () => store('userInfo')?.direction > 0;

// 处理订单、仓位列表方向，根据用户方向
export const handleDirection = (res: any, list: any) => {
  if (getUserDirection()) return res;
  return list.filter((item: any) => item !== res)[0];
};

// 结合size和方向计算总方向
export const getDirection = (size: any) => (getUserDirectionNum() * size > 0 ? true : false);

// 全仓逐仓信息
export const cangWeiTypes: any = { all: '全仓', zhu: '逐仓' };

// 下单时校验余额
export function checkKeYongMoney(keYongMoney: any) {
  // 下单最小可用资金标准
  const biaoZhun = 10;
  if (+keYongMoney < biaoZhun) {
    message.error('可用资金不足，请充值');
    return false;
  }
  return true;
}

// 精度数字求和
export function jingDuSum(list: any[]) {
  if (!Array.isArray(list)) return 0;
  let sum = jingDuNum(0);
  for (let item of list) {
    sum = sum.add(jingDuNum(item));
  }
  return +sum;
}

// 加法
export function jiaFa(list: any[]) {
  if (!Array.isArray(list)) return 0;
  let sum = jingDuNum(0);
  for (let item of list) {
    sum = sum.add(jingDuNum(item));
  }
  return +sum;
}

// 乘法
export function chengFa(list: any[]) {
  if (!Array.isArray(list)) return 0;
  let res = jingDuNum(1);
  for (let item of list) {
    res = res.times(jingDuNum(item));
  }
  return +res;
}

// 除法
export const chuFa = (n1: any, n2: any) => +jingDuNum(n1).div(jingDuNum(n2));

// 处理已实现盈亏信ysxYingKui息
export function ysxYingKui(item: any) {
  const direction = store.get('userInfo')?.direction;
  const { pnl_pnl, pnl_fee, pnl_fund } = item;
  const pnl_pnl_new = direction * pnl_pnl;
  const old_pnl_fee = pnl_fee;
  const pnl_fee_new = +jingDuNum(pnl_fee).times(jingDuNum(1.4));
  const pnl_new = jingDuSum([pnl_pnl_new, pnl_fund, pnl_fee_new]);
  return {
    pnl: pnl_new,
    pnl_pnl: pnl_pnl_new,
    pnl_fee: pnl_fee_new,
    pnl_fund,
    old_pnl_fee,
  };
}

// 处理未实现盈亏: +8%
export function weiShiXianYingKui(record: any) {
  const bili = 0.08;
  const direction = store.get('userInfo')?.direction;
  const baoZhengJin = Number(record?.leverage !== '0' ? record?.margin : record?.initial_margin);
  const oldHuiBaoLv = (record?.unrealised_pnl / baoZhengJin) * direction;
  const oldNum = record?.unrealised_pnl * direction;
  return {
    num: jingDuSum([oldNum, Math.abs(oldNum) * bili]),
    huiBaoLv: jingDuSum([oldHuiBaoLv, bili]),
    oldNum,
    oldHuiBaoLv,
  };
}

// 计算止盈止损触发价
// 止盈触发价 = 开仓均价 x(1 + 收益率 / 杠杆) / [(1 - (收益率  x 手续费率) / 持仓数量)]
export function zhiYingSunTriggerPrice(shouYiLv: any, formData: any, shouXuFeiLv: any) {
  if (shouXuFeiLv === 0 || Math.abs(shouYiLv) === 0) return null;
  const kaiChanJunJia = formData?.entry_price;
  const gangGan = formData?.leverInfo?.lever;
  const num = Math.abs(formData?.size);
  // console.log(shouYiLv, kaiChanJunJia, gangGan, num, shouXuFeiLv);
  const shouYiGangGan = jiaFa([1, chuFa(shouYiLv, gangGan)]); // // 收益率,杠杆
  const shouYiLvShouXu = chengFa([shouYiLv, shouXuFeiLv]) * -1; // 收益率,手续费率
  const houBian = jiaFa([1, chuFa(shouYiLvShouXu, num)]);
  const chengFirst = chengFa([kaiChanJunJia, shouYiGangGan]); // 乘法1
  const price = chuFa(chengFirst, houBian).toFixed(1);
  return price;
}

// 根据止盈止损价反推收益率
export function getShouYiLvByPrice(price: any, formData: any, shouXuFeiLv: any) {
  // 收益率 = (止盈触发价 - 开仓均价) / ((止盈触发价 * 手续费率) / 持仓数量 + (开仓均价 / 杠杆))
  const kaiChanJunJia = formData?.entry_price;
  const gangGan = +formData?.leverInfo?.lever;
  const num = Math.abs(formData?.size);
  const res =
    ((price - kaiChanJunJia) / ((price * shouXuFeiLv) / num + kaiChanJunJia / gangGan)) * 100;
  const shouYiLv = Math.abs(+res.toFixed(0));
  console.log('shouYiLv: ', shouYiLv);
  return shouYiLv;
}

/*
爆仓 ?
591
盈亏 = 仓位大小 × 合约乘数 ×（平仓价格 - 开仓均价）
回报率 = 未实现盈亏 / 仓位保证金
      =  [仓位大小 × 合约乘数 × (标记价格 - 开仓均价) ] / (起始保证金 + 平仓手续费)

未实现盈亏 unrealised_pnl
起始保证金 initial_margin
平仓手续费?
回报率 = unrealised_pnl / (initial_margin + 平仓手续费)

收益率
开仓均价 * (1+收益率) = 止盈触发价
83591.6 82747.6  100% 5.06 10

你好，我想请教下，止盈触发价如何通过收益率计算出来的，计算公式是啥

回报率 = 未实现盈亏 / 仓位保证金

未实现盈亏 = 保证金 * 回报率
止盈触发价 = 开仓均价 + 未实现盈亏
止盈触发价 = 开仓均价 - 未实现盈亏
90856.8 - 82747.6 = 8109

# ====== 止盈止损率计算
maker_fee_rate
止盈触发价 = 开仓均价 x ( 1+ 收益率/杠杆)  / (1- (收益率  x 手续费率) / 持仓数量)
"AUTO_INVALID_PARAM_TRIGGER_PRICE: invalid argument: trigger.price price is not an integer multiple of a price unit"

## 回填
参数：
  开仓价格 83181.2
  收益率 120%
  杠杆 90
  手续费率 0.0002
  持仓数量 12
  止盈触发价 84292

收益率 = ( 止盈触发价 - 开仓均价) / ( (止盈触发价 * 手续费率) / 持仓数量 + (开仓均价 / 杠杆 ))

// 爆仓
gate-key:9b3124a4de9e42da286d1ec2730de34c
gate-secret:c0706eb4f42c91d870cd01a6f78959b332470dffb4e71017147f8193c2e536a2

<!-- 爆仓 -->
{
  contract: 'BTC_USDT',
  text: 't-h-5-1743410298-bc',
  price: 0,
  size: 0,
  tif: 'ioc',
  close: true,
  stp_act: '-'
}

{
    "contract": "BTC_USDT",
    "text": "t-h-5-1743410387",
    "price": 0,
    "size": 0,
    "tif": "ioc",
    "close": true,
    "stp_act": "-"
}
     
407
192.686137592106
20.97


*/
